package com.easyidea.its.web.filter;

import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.easyidea.its.util.ItsConstants;
import com.easyidea.its.util.RequestUtil;
import com.easyidea.its.web.dto.SeesionUserDto;

public class PermissionFilter implements Filter {

	/**
	 * 
	 */
	protected Log log = LogFactory.getLog(this.getClass());

	/** No permission url. */
	public static final String NOPERMURL = "/common/noPermission.action";

	// *********************************************************************
	// Initialization

	public void init(FilterConfig config) throws ServletException {
		log.debug("Init Permission Filter");
	}

	// *********************************************************************
	// Filter processing

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain fc) throws ServletException, IOException {
		if (log.isDebugEnabled()) {
			log.debug("Entering doFilter()");
		}

		request.setCharacterEncoding("utf-8");

		// make sure we've got an HTTP request
		if (!(request instanceof HttpServletRequest)
				|| !(response instanceof HttpServletResponse)) {
			log.error("doFilter() called on a request or response"
					+ " that was not an HttpServletRequest or response.");
			throw new ServletException(
					"PermissionFilter protects only HTTP resources");
		}

		if (!hasPermission(request)) {
			log.error("PermissionFilter.intercept no perm");
			redirectToNoPermission((HttpServletRequest) request,
					(HttpServletResponse) response);
			return;
		}

		fc.doFilter(request, response);
		return;
	}

	/*
	 * Permission check
	 */
	@SuppressWarnings("unchecked")
	private boolean hasPermission(ServletRequest request) {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String servletPath = httpServletRequest.getServletPath();

		String queryString = httpServletRequest.getQueryString();
		if (servletPath.startsWith("common")
				|| servletPath.startsWith("auth/common")) {
			return true;
		}

		final String requestUrl = servletPath;
		if (log.isDebugEnabled()) {
			log.debug("Permission check key:" + requestUrl);
		}

		SeesionUserDto userdto = (SeesionUserDto) httpServletRequest
				.getSession().getAttribute(ItsConstants.SESSION_KEY_USER_INFO);
		if (null == userdto) {
			return false;
		}
		List<String> permissionUrlList = userdto.getPermissionUrlList();
		if (null == permissionUrlList) {
			return false;
		}
		if (CollectionUtils.exists(permissionUrlList, new Predicate() {
			public boolean evaluate(Object input) {
				if (log.isDebugEnabled()) {
					log.debug("Check actionPerms:" + input);
				}
				if (requestUrl.indexOf((String) input) != -1) {
					return true;
				}
				return false;
			}
		})) {
			return true;
		}
		return !CollectionUtils.exists(ItsConstants.getAllPermissionUrlList(),
				new Predicate() {
					public boolean evaluate(Object input) {
						if (log.isDebugEnabled()) {
							log.debug("Check actionPerms:" + input);
						}
						if (requestUrl.indexOf((String) input) != -1) {
							return true;
						}
						return false;
					}
				});
	}

	/**
	 * Redirects the request to no permission page
	 */
	private void redirectToNoPermission(HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		if (log.isDebugEnabled()) {
			log.debug("entering redirectToNoPermission()");
		}
		String noPermString = RequestUtil.buildServerURL(request) + NOPERMURL;

		if (log.isDebugEnabled()) {
			log.debug("Redirecting browser to [" + noPermString + ")");
		}
		((HttpServletResponse) response).sendRedirect(noPermString);

		if (log.isDebugEnabled()) {
			log.debug("returning from redirectToNoPermission()");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

}
